package org.ee.system.service;

import org.ee.system.domain.Menu;
import org.ee.system.reository.MenuRepository;
import org.ee.system.vo.MenuVo;
import org.ee.system.vo.RouteRecord;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author zlj
 * @Date 2025/8/30 07:55
 */
@Service
public class MenuService {

    private final MenuRepository menuRepository;

    public MenuService(MenuRepository menuRepository) {
        this.menuRepository = menuRepository;
    }

    public List<MenuVo> findAll() {
        return null;
    }

    public List<RouteRecord> getMenuTree(){
        List<Menu> menus=menuRepository.findAll();
        return buildMenuTree(menus);
    }

    public List<RouteRecord> buildMenuTree(List<Menu> menus) {
        Map<Long, RouteRecord> map = menus.stream()
                .map(this::toRoute)
                .collect(Collectors.toMap(RouteRecord::getId, Function.identity()));

        List<RouteRecord> roots = new ArrayList<>();
        for (RouteRecord route: map.values()) {
            if (route.getParentId() == null || route.getParentId() == 0) {
                roots.add(route);
            } else {
                RouteRecord parent = map.get(route.getParentId());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(route);
                }
            }
        }
        // 排序
        //roots.sort(Comparator.comparing(RouteRecord::getSortNum));
        return roots;
    }
    // 把 Menu 转成 MenuVo（请保证 Menu 的 parent 字段可以安全访问）
    private MenuVo toVo(Menu m) {
        MenuVo vo = new MenuVo();
        vo.setId(m.getId());
        vo.setName(m.getName());
        vo.setPath(m.getPath());
        vo.setComponent(m.getComponent());
        vo.setIcon(m.getIcon());
        vo.setShowBadge(m.getShowBadge());
        vo.setShowTextBadge(m.getShowTextBadge());
        vo.setHide(m.getHide());
        vo.setHideTab(m.getHideTab());
        vo.setLink(m.getLink());
        vo.setIframe(m.getIframe());
        vo.setKeepAlive(m.getKeepAlive());
        vo.setFirstLevel(m.getFirstLevel());
        vo.setFullPage(m.getFullPage());
        vo.setSortNum(m.getSortNum() == null ? 0 : m.getSortNum());

        // 注意：Menu 中 parent 是 Menu 对象，这里要小心懒加载
        if (m.getParent() != null) {
            // 如果 Hibernate session 可能已关闭，请确保在 DAO 查询时 fetch parentId，或者通过 SQL/DTO 一次查询好 parentId
            vo.setParentId(m.getParent().getId());
            vo.setParentName(m.getParent().getName());
        } else {
            vo.setParentId(0L);
        }
        return vo;
    }

    // 递归排序子树
    private void sortTree(List<MenuVo> list) {
        if (list == null || list.isEmpty()) return;
        list.sort(Comparator.comparing(MenuVo::getSortNum, Comparator.nullsFirst(Integer::compareTo)));
        for (MenuVo vo : list) {
            sortTree(vo.getChildren());
        }
    }

    private RouteRecord toRoute(Menu m) {
        RouteRecord route = new RouteRecord();
        route.setId(m.getId());
        route.setPath(m.getPath());
        route.setName(m.getName());
        route.setComponent(m.getComponent());
        route.setParentId(m.getParent() != null ? m.getParent().getId() : 0L);

        RouteRecord.RouteMeta meta = new RouteRecord.RouteMeta();
        meta.setTitle(m.getName());
        meta.setIcon(m.getIcon());
        meta.setHide(m.getHide());
        meta.setHideTab(m.getHideTab());
        meta.setKeepAlive(m.getKeepAlive());
        meta.setFirstLevel(m.getFirstLevel());
        meta.setFullPage(m.getFullPage());
        meta.setShowBadge(m.getShowBadge());
        meta.setShowTextBadge(m.getShowTextBadge());
        meta.setLink(m.getLink());
        meta.setIframe(m.getIframe());

        route.setMeta(meta);
        return route;
    }


}
